package com.taobao.client.component.templete;

import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;

/**
 * Parses Element to Widget
 * 
 * @author crane.ding
 * @version 1.0 2008-11-21
 */
public class AutoRebindWidget {

	/**
	 * Parses Element to Widget<br>
	 * if the element is null or error will return null.<br>
	 * 
	 * @param el
	 *            Page's Element
	 * @return Widget <? extends Widget>
	 */
	public static Widget rebindWidget(Element el) {
		Widget widget = null;

		if ((widget = mustBeImage(el)) != null)
			return widget;
		if ((widget = mustBeListBox(el)) != null)
			return widget;
		if ((widget = mustBeButton(el)) != null)
			return widget;
		if ((widget = mustBePassword(el)) != null)
			return widget;
		if ((widget = mustBeRadioButton(el)) != null)
			return widget;
		if ((widget = mustBeCheckBox(el)) != null)
			return widget;
		if ((widget = mustBeTextArea(el)) != null)
			return widget;
		if ((widget = mustBeTextBox(el)) != null)
			return widget;
		if ((widget = mustBeHTML(el)) != null)
			return widget;
		
		if (el != null)
			return HTML.wrap(el);

		return widget;
	}

	private static String getTagName(Element el) {
		String tagName = el.getTagName();
		if (tagName == null)
			return "";
		return tagName;
	}

	private static ListBox mustBeListBox(Element el) {
		if (getTagName(el).equalsIgnoreCase("select"))
			return new ListBox(el);
		return null;
	}

	private static CheckBox mustBeCheckBox(Element el) {
		String type = DOM.getElementAttribute(el, "type");
		boolean isInput = getTagName(el).equalsIgnoreCase("input");
		if (isInput && type.equalsIgnoreCase("checkbox")){			
			return new CheckBox(el);
		}
		return null;
	}

	private static RadioButton mustBeRadioButton(Element el) {
		String type = DOM.getElementAttribute(el, "type");
		boolean isInput = getTagName(el).equalsIgnoreCase("input");
		if (isInput && type.equalsIgnoreCase("radio")){
			RadioButton button = new RadioButton(el);
			String label = DOM.getElementAttribute(el, "gwtLabel");
			if(label!=null)
				button.setText(label);
			return button;
		}
		return null;
	}

	
	private static HTML mustBeHTML(Element el) {
		String tagName = el.getTagName();
		if(getTagName(el).equalsIgnoreCase("span")|| tagName.equalsIgnoreCase("a")){
			return new BindHTML(el);
		} else if (tagName.equalsIgnoreCase("div")) {
			return new BindHTML(el);//new HTML(DOM.toString(el));
		}
		return null;
	}

	private static PasswordTextBox mustBePassword(Element el) {
		String type = DOM.getElementAttribute(el, "type");
		boolean isInput = getTagName(el).equalsIgnoreCase("input");
		if (isInput && type.equalsIgnoreCase("PASSWORD"))
			return new PasswordTextBox(el);
		return null;
	}

	private static TextBox mustBeTextBox(Element el) {
		if (getTagName(el).equalsIgnoreCase("input")){
			return new TextBox(el);
		}
		return null;
	}

	private static Button mustBeButton(Element el) {
		String type = DOM.getElementAttribute(el, "type");
		boolean isInput = getTagName(el).equalsIgnoreCase("input");
		if (isInput && type.equalsIgnoreCase("button"))
			return new BindButton(el);
		if (getTagName(el).equalsIgnoreCase("button"))
			return new BindButton(el);
		return null;
	}

	private static TextArea mustBeTextArea(Element el) {
		if (getTagName(el).equalsIgnoreCase("textarea"))
			return new TextArea(el);
		return null;
	}

	private static Image mustBeImage(Element el) {
		if (getTagName(el).equalsIgnoreCase("img"))
			return new Image(el);
		return null;
	}

	public static class CheckBox extends com.google.gwt.user.client.ui.CheckBox {
		public CheckBox(Element element) {
			super(getElementAttribute(element, "info"));
		}
	}
	
	public static class TextBox extends com.google.gwt.user.client.ui.TextBox {
		public TextBox(Element element) {
			super(element);
		}
	}
	
	public static class PasswordTextBox extends com.google.gwt.user.client.ui.PasswordTextBox {
		public PasswordTextBox(Element element) {
			super(element);
		}
	}
	
	public static class ListBox extends com.google.gwt.user.client.ui.ListBox {
		public ListBox(Element element) {
			super(element);
		}
	}
	
	public static class Image extends com.google.gwt.user.client.ui.Image {
		public Image(Element element) {
			super(element);
			sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS | Event.ONLOAD
			          | Event.ONERROR | Event.ONMOUSEWHEEL);
		}
		public void setUrl(String url) {
			this.getImageElement().setSrc(url);
		 }
		
		 private ImageElement getImageElement() {
			return getElement().cast();
		 }
	}

	public static class RadioButton extends
			com.google.gwt.user.client.ui.RadioButton {
		public RadioButton(Element element) {
			super(getElementAttribute(element, "name"), getElementAttribute(
					element, "info"));
			setValue(getElementAttribute(element, "value"));
		}

		public void setValue(String value) {
		}

		public Boolean getValue() {
			return super.getValue();
		}
//		public String getValue() {
//			return value;
//		}
	}

	public static class TextArea extends com.google.gwt.user.client.ui.TextArea {
		public TextArea(Element elem) {
			super();
			sinkEvents(Event.ONCHANGE);
		}
	}

	
	protected static native void removeAttribute(Element element, String name) /*-{
		element.removeAttribute(name);
	}-*/;

	protected static native String getElementAttribute(Element element,
			String attr) /*-{
		return element.getAttribute(attr);
	}-*/;

	protected static native void replaceChild(Element parent, Element newChild,
			Element oldChild) /*-{
		parent.replaceChild(newChild, oldChild);
	}-*/;
}
